﻿// ------------------------------------------------------------------------------------
//      Copyright (c) 2012 uhavemyword@gmail.com. All rights reserved.
//      Created by Ben at 12/24/2012 7:13:16 PM
// ------------------------------------------------------------------------------------

namespace CP.NLayer.Data.Test
{
    using System;
    using System.IO;
    using System.Linq;
    using CP.NLayer.Models.Entities;
    using Microsoft.Practices.Unity;
    using Microsoft.VisualStudio.TestTools.UnitTesting;

    [TestClass]
    public class CrudTest
    {
        [TestMethod]
        public void DbInitializeTest()
        {
            MyDbUtility.InitializeDatabase();
        }

        [TestMethod]
        public void WriteEdmxTest()
        {
            string filePath = Path.Combine(Directory.GetCurrentDirectory() + @"..\..\..\..\..\db\MyDb.edmx");
            MyDbUtility.WriteEdmx(filePath);
        }

        [TestMethod]
        public void InsertTest()
        {
            using (var worker = DependencyInjection.Container.Resolve<IUnitOfWork>())
            {
                var roleRepository = worker.GetRepository<Role>();
                var oldCount = roleRepository.Table.Count();

                var role = new Role { Name = Guid.NewGuid().ToString() };
                roleRepository.Add(role);
                worker.SaveChanges();

                var newCount = roleRepository.Table.Count();
                Assert.AreEqual<int>(oldCount + 1, newCount);
            }
        }

        [TestMethod]
        public void UpdateTest()
        {
            string oldValue;
            string newValue;
            string id;
            using (var worker = DependencyInjection.Container.Resolve<IUnitOfWork>())
            {
                var roleRepository = worker.GetRepository<Role>();
                var role = roleRepository.Table.FirstOrDefault();
                id = role.Id;
                oldValue = role.Name;
                do
                {
                    newValue = Guid.NewGuid().ToString();
                }
                while (newValue == oldValue);
                role.Name = newValue;
                roleRepository.Update(role);
                worker.SaveChanges();
            }

            using (var worker = DependencyInjection.Container.Resolve<IUnitOfWork>())
            {
                var roleRepository = worker.GetRepository<Role>();
                var role = roleRepository.GetById(id);
                Assert.AreNotEqual(oldValue, role.Name);
                Assert.AreEqual(newValue, role.Name);
            }
        }

        [TestMethod]
        public void DeleteTest()
        {
            using (var worker = DependencyInjection.Container.Resolve<IUnitOfWork>())
            {
                var roleRepository = worker.GetRepository<Role>();
                var preCount = roleRepository.Table.Count();

                var role = roleRepository.Table.FirstOrDefault();
                roleRepository.Remove(role);
                worker.SaveChanges();

                var postCount = roleRepository.Table.Count();
                Assert.AreEqual<int>(preCount - 1, postCount);
            }
        }

        [TestMethod]
        public void ConcurrencyTest()
        {
            using (var worker = DependencyInjection.Container.Resolve<IUnitOfWork>())
            {
                var roleRepository = worker.GetRepository<Role>();
                var role = roleRepository.Table.FirstOrDefault();
                var id = role.Id;
                role.Name = "name";

                using (var worker2 = DependencyInjection.Container.Resolve<IUnitOfWork>())
                {
                    var roleRepository2 = worker2.GetRepository<Role>();
                    var role2 = roleRepository2.GetById(id);
                    role2.Name = "name2";
                    roleRepository2.Update(role2);
                    worker2.SaveChanges();
                }

                roleRepository.Update(role);
                bool error = false;
                try
                {
                    worker.SaveChanges();
                }
                catch (Exception e)
                {
                    error = true;
                    Console.WriteLine(e.Message);
                }

                Assert.IsTrue(error, "Test failed. Expect an exception occurs.");
            }
        }
    }
}
